package com.meowcook.utils;

import com.meowcook.config.COSConfig;
import com.meowcook.exception.FileUploadException;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.model.PutObjectRequest;
import com.qcloud.cos.model.UploadResult;
import com.qcloud.cos.region.Region;
import com.qcloud.cos.transfer.TransferManager;
import com.qcloud.cos.transfer.Upload;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created with Intellij IDEA.
 * Description:
 * User: 28792
 * Date: 2025-05-12
 * Time: 15:40
 */
@Slf4j
public class COSClientUtils {

    private final static COSConfig cosConfig = SpringBeanUtils.getBean(COSConfig.class);

    private final static COSCredentials cred = new BasicCOSCredentials(cosConfig.getSecretId(), cosConfig.getSecretKey());

    private final static ClientConfig clientConfig = new ClientConfig(new Region(cosConfig.getReg()));

    /**
     * 将MultipartFile转换为临时File
     * @param file 未转化的文件
     * @return 临时File
     * @throws IOException 文件转化失败
     */
    private static File transferToTempFile(MultipartFile file) throws IOException {
        String originalFilename = file.getOriginalFilename();
        assert originalFilename != null;
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
        File tempFile = File.createTempFile("temp", suffix);
        file.transferTo(tempFile);
        return tempFile;
    }

    /**
     * 将文件上传至COS
     * @param localFile 由MultipartFile转化的临时文件
     * @param key 文件在COS中的路径
     * @return 文件的访问路径
     * @throws InterruptedException 文件上传失败
     */
    private static String uploadFileToCOS(File localFile, String key) throws InterruptedException {
        COSClient cosClient = new COSClient(cred, clientConfig);
        PutObjectRequest putObjectRequest = new PutObjectRequest(cosConfig.getBucket(), key, localFile);
        // 指定线程个数，不指定默认为单线程
        ExecutorService threadPool = Executors.newFixedThreadPool(8);
        TransferManager transferManager = new TransferManager(cosClient, threadPool);
        // 生成upload，并等待结束
        Upload upload = transferManager.upload(putObjectRequest);
        UploadResult uploadResult = upload.waitForUploadResult();
        // 获取文件访问路径
        URL url = cosClient.getObjectUrl(cosConfig.getBucket(), uploadResult.getKey());
        transferManager.shutdownNow();
        cosClient.shutdown();
        return cosConfig.getDomain() + url.getPath();
    }

    /**
     * 上传文件
     * @param file 文件
     * @param folder 文件夹
     * @return 文件访问路径
     * @throws InterruptedException 文件上传失败
     */
    public static String uploadFile(MultipartFile file, String folder) throws InterruptedException {
        String id = UUIDUtil.UUID_32();
        String fileName = id + file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
        String key = folder + "/" + fileName;
        File localFile = null;
        try {
            localFile = transferToTempFile(file);
            return uploadFileToCOS(localFile, key);
        } catch (IOException e) {
            throw new FileUploadException("文件上传失败");
        } finally {
            localFile.delete();
        }
    }

    /**
     * 删除文件
     * @param path 文件路径
     */
    public static void deleteFile(String path) {
        String[] split = path.split("/", 2);
        COSClient cosClient = new COSClient(cred, clientConfig);
        cosClient.deleteObject(cosConfig.getBucket(), split[1]);
        cosClient.shutdown();
    }
}
